﻿namespace com.crownpack
{
    using System.Collections.Generic;

    using com.crownpack.Extensions.StringExtensions;

    using Microsoft.BusinessData.MetadataModel;
    using Microsoft.BusinessData.Runtime;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint.BusinessData.SharedService;

    using ReferenceObject = Customer;

    /// <summary>
    /// References the following:
    /// ...\14\ISAPI\Microsoft.BusinessData.dll
    /// </summary>
    public class LOBDao
    {
        #region Fields

        public const string ListName = "CustomerList";

        #endregion Fields

        #region Constructors

        public LOBDao( string currentWebUrl )
        {
            CurrentWebUrl = currentWebUrl;
        }

        public LOBDao( )
        {
            CurrentWebUrl = SPContext.Current.Web.Url;
        }

        #endregion Constructors

        #region Properties

        string CurrentWebUrl
        {
            get;
            set;
        }

        #endregion Properties

        #region Methods

        public ReferenceObject GetByLocationNo( int parentCustomerNo, int locationNo )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    using ( new SPServiceContextScope( SPServiceContext.GetContext( spSite ) ) )
                    {
                        BdcService service = SPFarm.Local.Services.GetValue<BdcService>( );
                        IMetadataCatalog catalog = service.GetDatabaseBackedMetadataCatalog( SPServiceContext.Current );

                        IEntity entity = catalog.GetEntity( spSite.Url, ListName );
                        ILobSystemInstance LobSysteminstance = entity.GetLobSystem( ).GetLobSystemInstances( )[ 0 ].Value;
                        IMethodInstance method = entity.GetMethodInstance( "Read List", MethodInstanceType.Finder );
                        IEntityInstanceEnumerator handle = entity.FindFiltered( method.GetFilters( ), LobSysteminstance );

                        ReferenceObject o = null;

                        while ( handle.MoveNext( ) )
                        {
                            if ( handle.Current[ Layout.ParentCustomerNo ].ToString( ).Equals( parentCustomerNo.ToString( ) ) )
                            {
                                if ( handle.Current[ Layout.LocationNo ].ToString( ).Equals( locationNo.ToString( ) ) )
                                {
                                    Dictionary<string, string> d = new Dictionary<string, string>( );
                                    foreach ( string key in Layout.Keys )
                                    {
                                        try
                                        {
                                            string value = handle.Current[ key ].ToString( );
                                            d.Add( key, value );
                                        }
                                        catch
                                        {
                                            IgnoreError( );
                                        }
                                    }
                                    if ( d.Count > 0 )
                                        o = new ReferenceObject( d );
                                    break;
                                }
                            }
                        }
                        return o;
                    }
                }
            }
        }

        public List<ReferenceObject> GetByParentCustomerNo( int parentCustomerNo )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    using ( new SPServiceContextScope( SPServiceContext.GetContext( spSite ) ) )
                    {
                        BdcService service = SPFarm.Local.Services.GetValue<BdcService>( );
                        IMetadataCatalog catalog = service.GetDatabaseBackedMetadataCatalog( SPServiceContext.Current );

                        IEntity entity = catalog.GetEntity( spSite.Url, ListName );
                        ILobSystemInstance LobSysteminstance = entity.GetLobSystem( ).GetLobSystemInstances( )[ 0 ].Value;
                        IMethodInstance method = entity.GetMethodInstance( "Read List", MethodInstanceType.Finder );
                        IEntityInstanceEnumerator handle = entity.FindFiltered( method.GetFilters( ), LobSysteminstance );

                        List<ReferenceObject> l = new List<ReferenceObject>( );

                        while ( handle.MoveNext( ) )
                        {
                            if ( handle.Current[ Layout.ParentCustomerNo ].ToString( ).Equals( parentCustomerNo.ToString( ) ) )
                            {
                                Dictionary<string, string> d = new Dictionary<string, string>( );
                                foreach ( string key in Layout.Keys )
                                {
                                    try
                                    {
                                        string value = handle.Current[ key ].ToString( );
                                        d.Add( key, value );
                                    }
                                    catch
                                    {
                                        IgnoreError( );
                                    }
                                }
                                if ( d.Count > 0 )
                                    l.Add( new ReferenceObject( d ) );
                            }
                        }
                        l.Sort( ( a, b ) => a.LocationName.TryTrim( ).CompareTo( b.LocationName.TryTrim( ) ) );
                        return l;
                    }
                }
            }
        }

        void IgnoreError( )
        {
            const string Notice = "This documents that the error condition is ignored.";
        }

        #endregion Methods
    }
}